﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;

namespace Comp476Project
{
    class Tower:NPC
    {
        //=====particle effects========
        //public List<Primitives3D.GeometricPrimitive> lazorBall;
        public List<Matrix> lazorBallWorld;
        public float lazorBallHover;
        public Matrix projection;
        public ParticleSystem effects;
        public Primitives3D.GeometricPrimitive sphere;
        public Primitives3D.GeometricPrimitive sp;
        public Vector3 spPosv;
        double timer, dt,timer1,dt1;
        public Tower(Primitives3D.SpherePrimitive sphere, Matrix proj, Model mod, Vector3 pos)
            : base(sphere, proj, mod, pos)
        {
            this.sp = sphere;
            spPosv = new Vector3(0, -100, 0);
            maxHealth = 3000;
            health = maxHealth;
            damage = 0;
            baseDamage = 75;
            viewRange = 0.1f;
            attackTimer = 500;
            damageTimer = 0;
            behaviour = AIState.NONE;

            // Hovering Ball
            //lazorBall = new List<Primitives3D.GeometricPrimitive>();
            //lazorBall.Add(new Primitives3D.SpherePrimitive(GraphicsDevice));
            //lazorBall.Add(new Primitives3D.CylinderPrimitive(GraphicsDevice));
            lazorBallWorld = new List<Matrix>();
            lazorBallWorld.Add(Matrix.CreateScale(0.0075f) * Matrix.CreateTranslation(pos.X, pos.Y + 0.0375f, pos.Z));
            //lazorBallWorld.Add(Matrix.CreateScale(0.001f, 0.01f, 0.001f) * Matrix.CreateTranslation(pos.X, pos.Y + 0.0375f, pos.Z));
            lazorBallHover = 0;
            projection = proj;

            //=====particles=====================
            this.sphere = sphere;
            timer = 0;
            dt = 5;
            Color smokeColor = Color.Black;

            float smokeDuration = 2000;

            effects = (new ParticleSystem(sphere,ref proj, 2, 10, smokeDuration, false, 0.0001f, 0.00005f, 0.00009f, smokeColor, true, 0.0001f,
                                                    0.00009f, false, new Vector3(pos.X, pos.Y+0.03f,pos.Z), new Vector3(0.00025f, 0.00010f, 0.00025f), new Vector3(0, 0.0002f, 0), new Vector3(0.00005f, 0, 0.00005f), new Vector3(0, 0, 0), 0));

        }

        public override void update(GameTime gameTime)
        {
            //========== half health ===========================
            if (health <= maxHealth/2)
            {

                timer += gameTime.ElapsedGameTime.TotalMilliseconds;
                if (timer > dt)
                {
                    //effects.Update(gameTime);      
                    effects.Update(gameTime);
                    timer = 0;
                }
            }
            //======Quarter health===============
            if (health <= maxHealth/4 && health !=0)
            {
                timer += gameTime.ElapsedGameTime.TotalMilliseconds;
                if (timer > dt)
                {
                    effects.color = Color.OrangeRed;
                    effects.Update(gameTime);
                    timer = 0;
                }
            }

            timer1 += gameTime.ElapsedGameTime.TotalMilliseconds;
            if (timer1 > dt1)
            {
                lazorBallHover = (lazorBallHover + 0.04f) % MathHelper.ToRadians(360);
                lazorBallWorld[0] = Matrix.CreateScale(0.0075f) * Matrix.CreateTranslation(position.X, position.Y + 0.0375f + (float)Math.Sin(lazorBallHover) * 0.003f, position.Z);
                //lazorBallWorld[0] *= Matrix.CreateTranslation(0, (float)Math.Sin(lazorBallHover) * 0.001f, 0);
                timer1 = 0;
            }
            if (behaviour == AIState.ATTACK)
                attack(gameTime);
            if (target != null)
                behaviour = AIState.ATTACK;

            base.update(gameTime);
        }
        public override void draw(Matrix view)
        {
            //effects.Draw(view);
            sphere.Draw(lazorBallWorld[0], view, projection, Color.Orange);
            //if (damageTimer > 0)
            //    lazorBall[1].Draw(lazorBallWorld[1], view, projection, Color.Red);
           //======= half health =====================
            if (health <= maxHealth/2)
            {
                effects.Draw(view);
            }
            if (health <= maxHealth / 4 && health != 0)
            {
                effects.Draw(view);
            }
            if (behaviour == AIState.ATTACK)
            {
                
                sp.Draw(Matrix.CreateScale(0.0045f) * Matrix.CreateTranslation(spPosv), view, projection, Color.Gold);
            }
            base.draw(view);
        }


        public void attack(GameTime gameTime)
        {
            Vector3 aim = target.position - this.position;
            float distance = aim.Length();
            
            aim.Normalize();

            float ang = (float)Math.Acos(Vector3.Dot(aim, this.direction));

            Vector3 cross = Vector3.Cross(aim, this.direction);
            if (cross.Y < 0)
                ang *= -1;

            if (ang < -0.1)
                direction = Vector3.Transform(direction, Matrix.CreateRotationY(0.1f));
            else if (ang > 0.1)
                direction = Vector3.Transform(direction, Matrix.CreateRotationY(-0.1f));

            // I'MA FIRIN' MAH LAZOOOOOR
            //lazorBallWorld[1] = Matrix.CreateScale(0.001f, distance, 0.001f) * Matrix.CreateTranslation(position.X, position.Y + 0.0375f + distance / 2, position.Z);


            damageTimer += (int)gameTime.ElapsedGameTime.TotalMilliseconds;
            //attack animation
            if (damageTimer >= attackTimer)
            {
                damage = baseDamage + (float)rand.NextDouble() * (3*baseDamage);
                spPosv = new Vector3(position.X, position.Y, position.Z);
                //Console.WriteLine("attacking");
                target.health -= damage;
                damageTimer = 0;
                
            }
            Vector3 tarDir = target.position - position;
            tarDir.Normalize();
            spPosv +=  tarDir* 0.001f;
            float distToTarget = (position - target.position).Length();
            //Console.WriteLine("distance: " + distToTarget);
            //Console.WriteLine("view range: " + viewRange);

            if (target.health <= 0 || distToTarget>viewRange)
            {
                target = null;
                //Console.WriteLine("far");
                behaviour = AIState.NONE;
            }

        }// end of attack

    }
}
